package com.jiaming.restaurant.api.trade.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiaming.restaurant.api.common.bean.vo.MyPageVO;
import com.jiaming.restaurant.api.common.exception.ApiException;
import com.jiaming.restaurant.api.trade.bean.entity.Trade;
import com.jiaming.restaurant.api.trade.bean.entity.TradeItem;
import com.jiaming.restaurant.api.trade.bean.vo.*;
import com.jiaming.restaurant.api.trade.constants.TradeBizConstants;
import com.jiaming.restaurant.api.trade.mapper.TradeMapper;
import com.jiaming.restaurant.api.trade.service.ITradeItemService;
import com.jiaming.restaurant.api.trade.service.ITradeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dragon
 * @create 2021-02-24 16:27
 */
@Service
public class TradeServiceImpl extends ServiceImpl<TradeMapper, Trade> implements ITradeService {

    @Autowired
    ITradeItemService tradeItemService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public TradeSaveDataVo saveTrade(TradeVo tradeVo) {
        //封装保存到订单表 trade
        Trade trade = new Trade();
        trade.setRestId(tradeVo.getRestId());
        trade.setTableId(tradeVo.getTableId());
        trade.setUserId(tradeVo.getUserId());
        trade.setTradeStatus(TradeBizConstants.no);
        trade.setRestName(tradeVo.getRestName());
        trade.setTableCode(trade.getTableCode());
        //创建唯一订单
        String now = LocalDateTimeUtil.format(LocalDateTimeUtil.now(), DatePattern.PURE_DATETIME_MS_PATTERN);
        String randomNumbers = RandomUtil.randomNumbers(6);
        String tradeId = now + randomNumbers;
        trade.setTradeId(tradeId);
        //计算总额
        List<GoodsVo> goods = tradeVo.getGoods();
        int amount = 0;
        for (GoodsVo g : goods) {
            amount += g.getPrice() * g.getTotal();
            //封装保存到订单表 tradeItem
            TradeItem tradeItem = new TradeItem();
            tradeItem.setGoodsId(g.getId());
            tradeItem.setTradeId(tradeId);
            tradeItem.setTotal(g.getTotal());
            tradeItem.setPrice(g.getPrice());

            tradeItemService.save(tradeItem);
        }
        trade.setAmount(amount);
        this.save(trade);
        TradeSaveDataVo tradeSaveDataVo = new TradeSaveDataVo();
        tradeSaveDataVo.setTradeId(tradeId);
        tradeSaveDataVo.setAmount(amount);
        return tradeSaveDataVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TradeSaveDataVo addTrade(AddGoodsVo addGoodsVo) {
        //获取订单信息
        QueryWrapper<Trade> tradeQueryWrapper = new QueryWrapper<>();
        String tradeId = addGoodsVo.getTradeId();
        Trade trade = this.getOne(tradeQueryWrapper.eq("trade_id", tradeId));
        //判断订单支付状态
        if(trade.getTradeStatus().equals(TradeBizConstants.no)){
            //如果已支付，不能追加商品
            TradeSaveDataVo tradeSaveDataVo = new TradeSaveDataVo();
            tradeSaveDataVo.setPayStatus(trade.getTradeStatus());
            return tradeSaveDataVo;
        }
        List<GoodsVo> goods = addGoodsVo.getGoods();
        //获取追加的商品
        //组装查询SQL的过滤条件
        QueryWrapper<TradeItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("trade_id",tradeId);

        //新增商品的总额
        int amount = 0;
        for (GoodsVo g : goods) {
            //计算新增商品的总额
            amount += g.getTotal() * g.getPrice();
            queryWrapper.eq("goods_id",g.getId());
            TradeItem item = tradeItemService.getOne(queryWrapper);
            if(item == null){
                TradeItem tradeItem = new TradeItem();
                tradeItem.setTotal(g.getTotal());
                tradeItem.setGoodsId(g.getId());
                tradeItem.setTradeId(addGoodsVo.getTradeId());
                tradeItem.setPrice(g.getPrice());
                //保存新增商品
                tradeItemService.save(tradeItem);
            }else{
                item.setTotal(g.getTotal() + item.getTotal());
                tradeItemService.updateById(item);
            }
        }
        trade.setAmount(amount + trade.getAmount());
        this.updateById(trade);
        TradeSaveDataVo tradeSaveDataVo = new TradeSaveDataVo();
        tradeSaveDataVo.setAmount(trade.getAmount());
        tradeSaveDataVo.setTradeId(addGoodsVo.getTradeId());
        return tradeSaveDataVo;
    }

    @Override
    public TradeInfoVo getByTradeId(String tradeId) {

        //根据交易订单ID查询订单表和订单明细表数据
        QueryWrapper<Trade> tradeWrapper = new QueryWrapper<>();
        tradeWrapper.eq("trade_id",tradeId);
        Trade trade = this.getOne(tradeWrapper);
        QueryWrapper<TradeItem> tradeItemWrapper = new QueryWrapper<>();
        tradeItemWrapper.eq("trade_id",tradeId);
        List<TradeItem> tradeItems = tradeItemService.list(tradeItemWrapper);


        //封装响应数据
        TradeInfoVo tradeInfoVo = new TradeInfoVo();
        tradeInfoVo.setId(trade.getId());
        tradeInfoVo.setAmount(trade.getAmount());
        tradeInfoVo.setCreateTime(trade.getCreateTime());
        tradeInfoVo.setPayTime(trade.getPayTime());
        tradeInfoVo.setRestId(trade.getRestId());
        tradeInfoVo.setRestName(trade.getRestName());
        tradeInfoVo.setTableId(trade.getTableId());
        tradeInfoVo.setTableCode(trade.getTableCode());
        tradeInfoVo.setTradeId(tradeId);
        tradeInfoVo.setTradeStatus(trade.getTradeStatus());
        tradeInfoVo.setUserId(trade.getUserId());
        List<GoodsVo> list = new ArrayList<>();
        for (TradeItem tradeItem : tradeItems) {
            GoodsVo goodsVo = new GoodsVo();
            goodsVo.setId(tradeItem.getGoodsId());
            goodsVo.setTotal(tradeItem.getTotal());
            goodsVo.setPrice(tradeItem.getPrice());
            goodsVo.setName(tradeItem.getName());
            list.add(goodsVo);
        }
        tradeInfoVo.setGoods(list);
        return tradeInfoVo;
    }

    @Override
    public TradeSaveDataVo pay(String tradeId, Integer amount) {
        //根据订单ID获取订单信息
        QueryWrapper<Trade> tradeWapper = new QueryWrapper<>();
        tradeWapper.eq("trade_id",tradeId);
        Trade trade = this.getOne(tradeWapper);

        int tradeAmount = trade.getAmount();
        //判断支付金额与订单是否一致
        if(amount != tradeAmount){
            //不一致
//            TradeSaveDataVo tradeSaveDataVo = new TradeSaveDataVo();
//            tradeSaveDataVo.setPayStatus(TradeBizConstants.AMOUNT_LESS);
            throw  new ApiException(TradeBizConstants.AMOUNT_LESS_MSG);
        }
        //判断订单是否支付

        if(trade.getTradeStatus().equals(TradeBizConstants.yes)){
//            TradeSaveDataVo tradeSaveDataVo = new TradeSaveDataVo();
//            tradeSaveDataVo.setPayStatus(TradeBizConstants.REPART_PAY);
//            return tradeSaveDataVo;
            throw  new ApiException(TradeBizConstants.AMOUNT_PAY_MSG);
        }

        //更改支付状态以及支付时间
        trade.setTradeStatus(TradeBizConstants.yes);
        trade.setPayTime(LocalDateTime.now());
        //更新订单记录
        this.updateById(trade);

        TradeSaveDataVo dataVo = new TradeSaveDataVo();
        dataVo.setTradeId(tradeId);
        dataVo.setPayStatus(TradeBizConstants.yes);
        dataVo.setAmount(amount);
        return dataVo;
    }

    @Override
    public MyPageVO<Trade> pageDetail(TradePageVo tradePgeVo) {
        //创建page对象
        Page<Trade> page = new Page<>();
        page.setCurrent(tradePgeVo.getPageNum());
        page.setSize(tradePgeVo.getPageSize());

        //组装分页筛选条件
        if(StrUtil.isNotEmpty(tradePgeVo.getGoodsName())){
            this.baseMapper.pageByGoodsName(page,tradePgeVo);
        }else {
            QueryWrapper<Trade> tradeWrapper = new QueryWrapper<>();
            tradeWrapper.eq("user_id", tradePgeVo.getUserId());
            String tradeId = tradePgeVo.getTradeId();
            if (StrUtil.isNotEmpty(tradeId)) {
                tradeWrapper.eq("trade_id", tradePgeVo.getTradeId());
            }
            Integer payStatus = tradePgeVo.getPayStatus();
            if (payStatus != null && payStatus > 0) {
                tradeWrapper.eq("pay_status", tradePgeVo.getPayStatus());
            }
            Integer minAmount = tradePgeVo.getMinAmount();
            if (minAmount != null && minAmount > 0) {
                tradeWrapper.ge("min_amount", tradePgeVo.getMinAmount());
            }
            Integer maxAmount = tradePgeVo.getMaxAmount();
            if (maxAmount != null && maxAmount > 0) {
                tradeWrapper.le("max_amount", tradePgeVo.getMaxAmount());
            }
            LocalDateTime startTime = tradePgeVo.getStartTime();
            if (startTime != null) {
                tradeWrapper.ge("create_time", startTime);
            }
            LocalDateTime endTime = tradePgeVo.getEndTime();
            if (endTime != null) {
                endTime = LocalDateTimeUtil.offset(endTime, 1, ChronoUnit.DAYS);
                tradeWrapper.gt("create_time", endTime);
            }

            this.page(page, tradeWrapper);
        }
        //封装控制层数据 并返回
        MyPageVO<Trade> myPageVO = new MyPageVO<>();
        myPageVO.setTotalPages(page.getPages());
        myPageVO.setTotalItems(page.getTotal());
        myPageVO.setPageSize(page.getSize());
        myPageVO.setItems(page.getRecords());
        return myPageVO;
    }
}
